package Drawable;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

import FPGrowth.FPTree;
import FPGrowth.FPTree.FPTreeNode;
import FPGrowth.FPTree.ItemPrefixSubtreeNode;


public class FPTreeUI {
	Font font = new Font("Serif", Font.PLAIN, 10);
	//FPTree fptree;
	FPTreeNode root;
	
	static HashMap<Short,Node> posHash = new HashMap();
	
	public FPTreeUI(FPTreeNode r){
		root = r;
	}
	//Paint Node
	private void paintNode(Graphics g,Node node,ItemPrefixSubtreeNode nodeBase){
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(new Color(101,119,245));
		g2d.fillOval(node.x, node.y, 60, 40);
		g2d.setColor(new Color(4,14,77));
		g2d.drawOval( node.x, node.y, 60, 40);
		g2d.setFont(font);
		g2d.setColor(Color.WHITE);
		if(nodeBase == null)
			g2d.drawString("NULL", node.x+10, node.y+23);
		else
			g2d.drawString(nodeBase.itemID+":"+nodeBase.support, node.x+10, node.y+23);
	}
	//Paint arrow between 2 nodes
	private void paintArrow(Graphics g,Point fromNode,Point toNode){
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(Color.BLACK);
	      g2d.drawLine(fromNode.x, fromNode.y, toNode.x, toNode.y);
	      
	      double dy = fromNode.y - toNode.y;  
	      double dx = fromNode.x - toNode.x;  
	      double theta = Math.atan2(dy,dx); 
	      if(theta<0){
	    	 theta=3*Math.PI/2-theta;
	      } 
	      g2d.setStroke(new BasicStroke(1f));                         
	      Polygon tmpPoly=new Polygon();
	      
	      tmpPoly.addPoint(toNode.x,toNode.y);                                   
	      tmpPoly.addPoint(toNode.x+5,toNode.y-5);
	      tmpPoly.addPoint(toNode.x-5,toNode.y-5);
	      tmpPoly.addPoint(toNode.x,toNode.y); 
	      g2d.rotate(-theta, toNode.x, toNode.y);
	      g2d.drawPolygon(tmpPoly);
	      g2d.fillPolygon(tmpPoly);
	      g2d.rotate(theta, toNode.x, toNode.y);
	}
	/* Draw group childs of 1 parent
	 * in: parent node, space, position to draw 
	 * */
	private void paintChildOfNode(Graphics g,FPTreeNode parent, int spaceForGroup, Point startPos){
		Node parentNode;
		int spaceBetweenLevel;
		int spaceBetweenNode;
		LinkedList<FPTreeNode> listChild = parent.childs;
		if(parent.node == null)
		{
			parentNode = posHash.get((short)0);
			if(parent.childs.size()>20)
				spaceBetweenNode = 500;
			else
				spaceBetweenNode = 300;
			spaceBetweenLevel = 400;
			
		}
		else{
			spaceBetweenNode = 400;
			spaceBetweenLevel = 300;
			parentNode = posHash.get(parent.node.itemID);
		}
		int k = 0;
		for(int i=0;i<listChild.size();i++){
			Node nodeToDraw = new Node(startPos.x + k,startPos.y);
			
			FPTreeNode nodeBase = parent.childs.get(i);
			posHash.put(nodeBase.node.itemID, nodeToDraw);
			paintNode(g,nodeToDraw,nodeBase.node);
			paintArrow(g,parentNode.from,nodeToDraw.to);
			
			k+=spaceBetweenNode;
			if(nodeBase.childs.size()==1)
				paintChildOfNode(g,nodeBase, 0,new Point(nodeToDraw.x, nodeToDraw.y + spaceBetweenLevel));
			else
				paintChildOfNode(g,nodeBase, 0,new Point(nodeToDraw.x-200, nodeToDraw.y + spaceBetweenLevel));
		}
	}
	public void paintFullTree(Graphics g){
		Node r;
		if(root.childs.size()>100)
			r = new Node(20000,10);
		else
			r = new Node(5000,10);
		posHash.put((short)0, r);
		paintNode(g,r, null);
		paintChildOfNode(g,root,200,new Point(5000,200));
		
	}
	
}
